package com.zkrt.upms.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zkrt.upms.dto.DevMqttDTO;
import com.zkrt.upms.dto.DevVarDTO;
import com.zkrt.upms.entity.DeviceAttrR;
import com.zkrt.upms.entity.DeviceB;
import com.zkrt.upms.entity.NotifyR;
import com.zkrt.upms.mapper.DeviceAttrRMapper;
import com.zkrt.upms.mapper.DeviceBMapper;
import com.zkrt.upms.mapper.NotifyRMapper;
import com.zkrt.upms.service.INotifyRService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
public class NotifyRServiceImpl implements INotifyRService {

    @Autowired
    private NotifyRMapper notifyRMapper;

    @Autowired
    private DeviceAttrRMapper attrRMapper;

    @Autowired
    private DeviceBMapper deviceMapper;

    /**
     * 消息记录
     * @param topic
     * @param payload
     * @return
     */
    private int recordNotify(final String topic, final String payload) {
        NotifyR notifyR = new NotifyR();
        notifyR.setTopic(topic);
        notifyR.setNotify(payload);
        notifyR.setCreateTime(new Date(System.currentTimeMillis()));
        int ident = notifyRMapper.insert(notifyR);
        if (ident > 0) {
//            log.info("\n[保存消息记录] -> \n{} : {}\n", ident>0, JSONObject.toJSONString(notifyR));
        }
        return ident;
    }

    /**
     * 保存消息记录
     * @param topic
     * @param payload
     */
    @Override
    public void saveNotify(final String topic, final String payload) {
        if (topic != null && payload != null) {
            int ident = recordNotify(topic, payload);
            if (ident > 0) {
                JSONObject json = JSONObject.parseObject(payload);
                if (json != null) {
                    if (json.containsKey("devList")) {
                        DevMqttDTO dto = JSONObject.parseObject(payload, DevMqttDTO.class);
                        if (dto != null) {
                            List<DevVarDTO> devList = dto.getDevList();
                            if (devList != null) {
                                Pattern pattern = Pattern.compile("/sys/(.+?)/up");
                                Matcher matcher = pattern.matcher(topic);
                                String gateWayCode = null;
                                if (matcher.find()) {
                                    gateWayCode = matcher.group(1);
                                }
                                String finalGateWayCode = gateWayCode; // 用于Lambda
                                devList.forEach(d -> {
                                    String sn = d.getDevSn();
                                    LambdaQueryWrapper<DeviceB> deviceWrapper = new LambdaQueryWrapper<>();

                                    deviceWrapper.eq(DeviceB::getSn, sn);
                                    deviceWrapper.eq(DeviceB::getDisabled, false);

                                    int isExists = deviceMapper.selectCount(deviceWrapper);
                                    if (isExists > 0) {
                                        JSONObject attrs = d.getVarList();
                                        if (attrs != null) {
                                            attrs.forEach((k,v) -> {
                                                LambdaQueryWrapper<DeviceAttrR> attrWrapper = new LambdaQueryWrapper<>();
                                                attrWrapper.eq(DeviceAttrR::getSn, sn);
                                                attrWrapper.eq(DeviceAttrR::getAttrKey, k);
                                                attrWrapper.last("limit 1");
                                                DeviceAttrR attrR = attrRMapper.selectOne(attrWrapper);
                                                if (attrR == null) {
                                                    attrR = new DeviceAttrR();
                                                }
                                                attrR.setSn(sn);
                                                attrR.setAttrKey(k);
                                                attrR.setAttrValue(String.valueOf(v));
                                                int attrIdent = 0;
                                                if (ObjectUtil.isNotEmpty(attrR.getId())) { // 修改
                                                    attrR.setUpdateTime(new Date(System.currentTimeMillis()));
                                                    attrIdent = attrRMapper.updateById(attrR);
                                                } else { // 新增
                                                    attrR.setCreateTime(new Date(System.currentTimeMillis()));
                                                    attrIdent = attrRMapper.insert(attrR);
                                                }
                                                if (attrIdent > 0) {
//                                                    log.info("\n[更新设备属性] -> \n{}\n", JSONObject.toJSONString(attrR));
                                                }
                                            });
                                        }
                                    }
                                });
                            }
                        }else {
                            log.info("处理mqtt消息为空:"+payload);
                        }
                    }else {
//                        log.info("未获取到devList:"+json);
                    }
                }else {
                    log.info("payload处理失败:"+payload);
                }
            }else {
                log.info("topic未找到:"+topic);
            }
        }
    }

    /**
     * 查询消息记录（分页）
     * @param current
     * @param size
     * @return
     */
    @Override
    public R page(Long current, Long size) {
        if (current == null) {
            current = 1l;
        }
        if (size == null) {
            size = 10l;
        }
        IPage<NotifyR> page = new Page<>(current, size);
        LambdaQueryWrapper<NotifyR> notifyWrapper = new LambdaQueryWrapper<>();
        notifyWrapper.orderByDesc(NotifyR::getCreateTime);
        page = notifyRMapper.selectPage(page, notifyWrapper);
        return R.ok(page);
    }

}
